//package com.echovin.esb.gateway.filter;
//
//import com.echovin.esb.discovery.ServiceDiscoveryFactory;
//import com.echovin.esb.discovery.pojo.ServiceInstance;
//import org.apache.logging.log4j.util.Strings;
//import org.springframework.cloud.gateway.filter.GatewayFilterChain;
//import org.springframework.cloud.gateway.filter.GlobalFilter;
//import org.springframework.cloud.gateway.support.NotFoundException;
//import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
//import org.springframework.core.Ordered;
//import org.springframework.stereotype.Component;
//import org.springframework.web.server.ServerWebExchange;
//import reactor.core.publisher.Mono;
//
//import java.net.URI;
//
//import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
//
////@Component
//public class CustomLoadBalancerClientFilter implements GlobalFilter, Ordered {
//
//    /**
//     * 服务发现配置文件地址，需配置
//     */
//    private final static String CONFIG_PATH = "/Users/sirenmac/Desktop/esbConfig/config";
//
//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        URI url = (URI)exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);
//        String schemePrefix = (String)exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR);
//
//        if (url != null && ("lb".equals(url.getScheme()) || "lb".equals(schemePrefix))) {
//            ServerWebExchangeUtils.addOriginalRequestUrl(exchange, url);
//            // 负载均衡发现实例
//            ServiceInstance instance = this.chooseInstance(url.getHost());
//            if (instance == null) {
//                throw new  NotFoundException("Unable to find instance for " + url.getHost());
//                //throw NotFoundException.create(true, "Unable to find instance for " + url.getHost());
//            } else {
//                URI uri = exchange.getRequest().getURI();
//                URI requestUrl = this.reconstructURIWithServer(instance, uri);
//                exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);
//                return chain.filter(exchange);
//            }
//        } else {
//            return chain.filter(exchange);
//        }
//    }
//
//    @Override
//    public int getOrder() {
//        // gateway自带LoadBalancerClientFilter排序数字为10100，
//        // RouterToRequsetUrlFilter排序数字为10000，
//        // 自定义数字介于他俩之间就可以替换系统的负载均衡
//        return 10001;
//    }
//
//    /**
//     * 服务发现
//     * @param serviceId
//     * @return
//     */
//    private ServiceInstance chooseInstance(String serviceId) {
//        ServiceDiscoveryFactory.INSTANCE.setConfigFilePath(CONFIG_PATH);
//        ServiceInstance instance = ServiceDiscoveryFactory.INSTANCE.selectOneHealthyInstance(serviceId);
//
//        return instance;
//    }
//
//    /**
//     * 组装最终服务实例的url
//     * @param instance
//     * @param original
//     * @return
//     */
//    private URI reconstructURIWithServer(ServiceInstance instance, URI original) {
//        String host = instance.getIp();
//        int port = instance.getPort();
//        String scheme = instance.isSecure() ? "https" : "http";
//        if (host.equals(original.getHost()) && port == original.getPort() && scheme == original.getScheme()) {
//            return original;
//        } else {
//            if (scheme == null) {
//                scheme = original.getScheme();
//            }
//            try {
//                StringBuilder sb = new StringBuilder();
//                sb.append(scheme).append("://");
//                if (!Strings.isEmpty(original.getRawUserInfo())) {
//                    sb.append(original.getRawUserInfo()).append("@");
//                }
//
//                sb.append(host);
//                if (port >= 0) {
//                    sb.append(":").append(port);
//                }
//
//                sb.append(original.getRawPath());
//                if (!Strings.isEmpty(original.getRawQuery())) {
//                    sb.append("?").append(original.getRawQuery());
//                }
//
//                if (!Strings.isEmpty(original.getRawFragment())) {
//                    sb.append("#").append(original.getRawFragment());
//                }
//
//                URI newURI = new URI(sb.toString());
//                return newURI;
//            } catch (Exception e) {
//                return null;
//            }
//        }
//    }
//
//}
